package com.sls.game.service.impl;

import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.ServerDateAndTime;
import com.sls.core.util.UtilMD5Encryption;
import com.sls.game.assist.Helper;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsOrderLogDAO;
import com.sls.game.parser.nutsnet.NutsNetAssembleHttpUrl;
import com.sls.game.parser.nutsnet.TradeResponseSaxParseXml;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.GoodsOrderLog;
import com.sls.game.pojo.NutsNetOrderQueryParameter;
import com.sls.game.pojo.NutsNetServerInfo;
import com.sls.game.pojo.NutsNetTradeResInfo;
import com.sls.game.service.NutsNetOrderQueryService;

/**
 * 
 * @description 坚果网络订单查询接口
 * @author Wangxuegang
 * @date 2012-9-4
 * 
 */
@Service("nutsNetOrderQueryService")
public class NutsNetOrderQueryServiceImpl implements NutsNetOrderQueryService {

	private static Logger log = Logger.getLogger(NutsNetTradeServiceImpl.class);

	private Gson gson = null;

	private GoodsOrderDAO goodsOrderDAO;

	private GoodsOrderLogDAO goodsOrderLogDAO;

	public GoodsOrderLogDAO getGoodsOrderLogDAO() {
		return goodsOrderLogDAO;
	}

	@Resource(name = "goodsOrderLogDAO")
	public void setGoodsOrderLogDAO(GoodsOrderLogDAO goodsOrderLogDAO) {
		this.goodsOrderLogDAO = goodsOrderLogDAO;
	}

	public GoodsOrderDAO getGoodsOrderDAO() {
		return goodsOrderDAO;
	}

	@Resource(name = "goodsOrderDAO")
	public void setGoodsOrderDAO(GoodsOrderDAO goodsOrderDAO) {
		this.goodsOrderDAO = goodsOrderDAO;
	}

	public NutsNetOrderQueryServiceImpl() {
		gson = CommonUtil.gson();
	}

	@Override
	public String saveQueryOrder(String body, Head head)
			throws ServerDisponseException {
		if (log.isInfoEnabled()) {
			log.info("进入Service开始处理[" + head.getRequestId() + "]的请求");
		}
		// 对消息body进行解析
		NutsNetOrderQueryParameter parameterInfo = gson.fromJson(body,
				NutsNetOrderQueryParameter.class);

		NutsNetServerInfo serverInfo = NutsNetAssembleHttpUrl.getKeyValue();
		String partnerKey = serverInfo.getPartnerKey(); // 为合作方商户密钥
		if (StringUtils.isNotEmpty(partnerKey)) {
			partnerKey = partnerKey.trim();
		}
		String supUserKey = serverInfo.getSupUserKey(); // 为合作方用户密钥
		if (StringUtils.isNotEmpty(supUserKey)) {
			supUserKey = supUserKey.trim();
		}
		String partnerId = serverInfo.getPartnerId(); // 合作平台编号
		if (StringUtils.isNotEmpty(partnerId)) {
			partnerId = partnerId.trim();
		}
		String supUserId = serverInfo.getSupUserId(); // 合作方用户编号
		if (StringUtils.isNotEmpty(supUserId)) {
			supUserId = supUserId.trim();
		}
		boolean flag = checkData(parameterInfo, head.getRequestId());
		if (flag) { // 数据校验通过
			try {
				String orderNo = parameterInfo.getPtOrderNo();
				GoodsOrderInfo order = this.goodsOrderDAO
						.queryByOrderId(orderNo);
				if (order == null) {
					NutsNetTradeResInfo respInfo = new NutsNetTradeResInfo();
					respInfo.setPtOrderNo(orderNo);
					respInfo.setStatus("ORDER_NOT_EXIST");
					return gson.toJson(respInfo);
				}
				// 签名字符串
				String sign = createSignStr(parameterInfo, partnerId,
						supUserId, partnerKey, supUserKey);

				String paraStr = assembleParameter(parameterInfo, partnerId,
						supUserId, sign);
				// 坚果网络接口服务path
				String path = "OrderStatus.aspx";
				String url = NutsNetAssembleHttpUrl.assembleHttpUrl(paraStr,
						path);
				// 发送http请求
				NutsNetTradeResInfo resInfo = sendHttpRequest(url);
				GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
				if (resInfo != null) {
					goodsOrderInfo.setOrderId(resInfo.getPtOrderNo());
					goodsOrderInfo.setResult(resInfo.getStatus());
					goodsOrderInfo.setSupOrderId(resInfo.getSupOrderNo());
					goodsOrderInfo.setSupOrderSuccessTime(resInfo
							.getSupOrderSuccessTime());

					String orderId = resInfo.getPtOrderNo();
					// 更新订单
					String status = ""; // 0：失败 1：成功 2：处理中 3：存疑 4 ：冲销 5: 订单不存在
										// 6: 其它
					if ("ORDER_SUCCESS".equals(resInfo.getStatus())) {
						status = "1";
					} else if ("ORDER_FAILED".equals(resInfo.getStatus())) {
						status = "0";
					} else if ("ORDER_UNDERWAY".equals(resInfo.getStatus())) {
						status = "2";
					} else if ("ORDER_NOT_EXIST".equals(resInfo.getStatus())) {
						status = "5";
					} else {
						status = "6";
					}
					goodsOrderInfo.setStatus(status);

					updateGoodsOrder(orderId, head, goodsOrderInfo);
				}

				String resultBody = null;
				if (resInfo != null) {
					resultBody = gson.toJson(resInfo);
				}
				if (log.isInfoEnabled()) {
					log.info("Service处理[" + head.getRequestId() + "]的请求已结束");
				}
				return resultBody;
			} catch (Exception e) {
				log.info("Service处理[" + head.getRequestId() + "]异常！");
				throw new ServerDisponseException(
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
			}
		}

		return null;
	}

	/**
	 * 生成签名字符串
	 * 
	 * @param paraInfo
	 * @param partnerId
	 * @param supUserId
	 * @param partnerKey
	 * @param supUserKey
	 * @return
	 */
	private String createSignStr(NutsNetOrderQueryParameter paraInfo,
			String partnerId, String supUserId, String partnerKey,
			String supUserKey) {
		String ptOrderNo = paraInfo.getPtOrderNo();
		String supOrderNo = paraInfo.getSupOrderNo();

		StringBuilder strBui = new StringBuilder();
		strBui.append("partnerId");
		strBui.append(partnerId);
		strBui.append("ptOrderNo");
		strBui.append(ptOrderNo);
		if (!("".equals(supOrderNo)) && supOrderNo != null) {
			strBui.append("supOrderNo");
			strBui.append(supOrderNo);
		}
		strBui.append("supUserId");
		strBui.append(supUserId);
		strBui.append(partnerKey);
		strBui.append(supUserKey);

		String data = strBui.toString();
		String signStr = UtilMD5Encryption.createMD5EncryptionOfGBK(data);
		if (StringUtils.isEmpty(signStr)) {
			throw new ServerDisponseException(
					ExceptionCodeDes.SIGN_ERROR.getCode(),
					ExceptionCodeDes.SIGN_ERROR.getDescription());
		}

		return signStr;
	}

	/**
	 * 数据校验
	 * 
	 * @throws ServerDisponseException
	 */
	private boolean checkData(NutsNetOrderQueryParameter parameterInfo,
			String reqId) throws ServerDisponseException {
		boolean flag = false;
		// 平台订单编号
		String ptOrderNo = parameterInfo.getPtOrderNo();
		if ("".equals(ptOrderNo) || ptOrderNo == null) {
			throw new ServerDisponseException(
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getCode(),
					ExceptionCodeDes.COOPERATION_PLATFORM_ORDERNO_NULL
							.getDescription());
		} else {
			flag = true;
		}

		return flag;
	}

	/**
	 * http请求url所传参数字符串拼接
	 * 
	 * @param sign
	 * @param supUserId
	 * @param partnerId
	 * 
	 * @param parameterInfo
	 * @return
	 */
	private String assembleParameter(NutsNetOrderQueryParameter paraInfo,
			String partnerId, String supUserId, String sign) {
		StringBuffer strBuf = new StringBuffer();
		strBuf.append("partnerId=");
		strBuf.append(partnerId);
		strBuf.append("&");
		strBuf.append("supUserId=");
		strBuf.append(supUserId);
		strBuf.append("&");
		strBuf.append("ptOrderNo=");
		strBuf.append(paraInfo.getPtOrderNo());
		String supOrderNo = paraInfo.getSupOrderNo();
		if (!("".equals(supOrderNo)) && supOrderNo != null) {
			strBuf.append("&");
			strBuf.append("supOrderNo=");
			strBuf.append(supOrderNo);
		}
		strBuf.append("&");
		strBuf.append("sign=");
		strBuf.append(sign);

		String paraStr = strBuf.toString();
		return paraStr;
	}

	/**
	 * 发送http请求，并对返回的xml格式的结果进行解析
	 * 
	 * @param url
	 * @return
	 */
	private NutsNetTradeResInfo sendHttpRequest(String url) {
		NutsNetTradeResInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		try {
			String supplyEncode = "GBK";
			String xmlStr = httpClient.doGet(url, supplyEncode);
			// 对返回的xml格式字符串数据进行解析
			List<NutsNetTradeResInfo> tradeResList = TradeResponseSaxParseXml
					.parseXmlString(xmlStr);
			if (tradeResList.size() > 0) {
				for (int i = 0; i < tradeResList.size(); i++) {
					resInfo = tradeResList.get(i);
				}
				return resInfo;
			}
		} catch (Exception e) {
			log.error(e);
		}

		return resInfo;
	}

	/**
	 * 根据交易返回的结果更新订单表
	 * 
	 * @param orderId
	 * @param head
	 * @param info
	 */
	private void updateGoodsOrder(String orderId, Head head, GoodsOrderInfo info) {
		String status = "";
		String supOrderNo = "";
		String supOrderSuccessTime = "";
		String cardNoPwd = "";
		String cardId = "";
		String orderResult = "";
		String isPay = "";
		String payTime = "";
		String paymentOrderNo = "";
		if (info != null) {
			status = info.getStatus();
			supOrderNo = info.getSupOrderId();
			supOrderSuccessTime = info.getSupOrderSuccessTime();
			cardNoPwd = info.getCardNoPwd();
			cardId = info.getCardsInformation();
			orderResult = info.getResult();
			isPay = info.getIsPay();
			payTime = info.getPayTime();
			paymentOrderNo = info.getPaymentOrderNo();
		}

		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		GoodsOrderInfo goodsOrderInfo1 = null;

		goodsOrderInfo.setOrderId(orderId);
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setSupOrderId(supOrderNo);
		goodsOrderInfo.setSupOrderSuccessTime(supOrderSuccessTime);
		goodsOrderInfo.setResult(orderResult);
		goodsOrderInfo.setIsPay(isPay);
		goodsOrderInfo.setPayTime(payTime);
		goodsOrderInfo.setPaymentOrderNo(paymentOrderNo);

		if (cardNoPwd != null && !("".equals(cardNoPwd))) { // 提取卡密时
			goodsOrderInfo.setCardsInformation(cardId);
			goodsOrderInfo.setCardNoPwd(cardNoPwd);
		}

		// 数据更新
		try {
			goodsOrderDAO.update(goodsOrderInfo);
		} catch (Exception e) {
			log.error(e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}

		// 订单日志更新
		try {
			goodsOrderInfo1 = this.goodsOrderDAO.queryByOrderId(orderId);
			if (goodsOrderInfo1 != null) {
				GoodsOrderLog orderLog = Helper.copy(goodsOrderInfo1);
				orderLog.setOrderId(orderId);
				orderLog.setId(UUID.randomUUID().toString());
				orderLog.setModifyTime(ServerDateAndTime
						.getNowDateTimeOfFormat());
				this.goodsOrderLogDAO.insert(orderLog);
			}
		} catch (Exception e) {
			log.error(e.toString());
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
	}

}
